#version 330 core

struct AmbientLight {
    vec3 color;
    vec3 intensity;
};


struct ParallelLight {
    vec3 direction;
    vec3 color;
    vec3 intensity;
};

in vec3 oPos;
in vec3 oCol;
in vec3 oNormal;
in vec2 oTexCoord;
in vec3 oWorldPos;

uniform AmbientLight uAmbientLight;
uniform ParallelLight uParallelLight;

uniform vec3 uCameraPos;

uniform sampler2D uDiffuseTex;
uniform sampler2D uSpecTex;

uniform float uShininess;

out vec4 oFragColor;

void main() {
    vec3 texCol = texture(uDiffuseTex, oTexCoord).rgb;
    vec3 specularMask = texture(uSpecTex, oTexCoord).rgb;

    // 计算环境光
    vec3 ambient = uAmbientLight.color.rgb * uAmbientLight.intensity.rgb;

    // 计算漫反射光
    vec3 n = normalize(oNormal);
    vec3 lightDir = normalize(uParallelLight.direction);
    float dif = clamp(dot(n, -lightDir), 0., 1.);
    vec3 diffuse = dif * uParallelLight.color.rgb * uParallelLight.intensity.xyz;

    // 计算镜面光
    float dotLN = dot(-lightDir, n); // 解决模型背部漏光问题
    float front = step(0.0, dotLN);
    vec3 viewDir = normalize(oWorldPos - uCameraPos);
    vec3 lightRefDir = normalize(reflect(lightDir, n));
    float spec = clamp(dot(lightRefDir, -viewDir), 0., 1.);
    spec = pow(spec, uShininess); // cos^x, 当x越大，整体图像越趋近于中间非常窄的正态分布，即高光区域会变小，直到缩窄为一个亮点
    vec3 specular = spec * uParallelLight.color.rgb * front * specularMask.r * 10.;

    vec3 col = (ambient + diffuse + specular) * texCol;

    oFragColor = vec4(col, 1.);
}